package com.example.rabbitmqspringbootdemo;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class AdvancedConfig {
    /*--------------------消息可靠性发送--------------------*/
    //开启 RabbitMQ 事务机制需要配置一个事务管理器
//    @Bean
//    RabbitTransactionManager transactionManager(ConnectionFactory connectionFactory) {
//        return new RabbitTransactionManager(connectionFactory);
//    }

    @Bean
    public Queue txQueue() {
        //另外三个参数值缺省为：true(持久化)、false(独占)、false(自动删除队列)
        //第五个可选参数是Map类型，用来设置额外属性。如arguments.put("x-message-ttl", 25000)用来设置25秒自动删除
        return QueueBuilder
                .durable("springTransactionQueue")
                .build();
    }

    @Bean
    public Queue confirmQueue() {
        //另外三个参数值缺省为：true(持久化)、false(独占)、false(自动删除队列)
        //第五个可选参数是Map类型，用来设置额外属性。如arguments.put("x-message-ttl", 25000)用来设置25秒自动删除
        return QueueBuilder
                .durable("springConfirmQueue")
                .build();
    }


//    @Bean
//    public DirectExchange txExchange() {
//        return (DirectExchange) ExchangeBuilder
//                .directExchange("springAckExchange")
//                .durable(true)
//                .build();
//    }

//    //配置绑定
//    @Bean
//    public Binding ackBinding(Queue txQueue, DirectExchange ackExchange) {
//        return BindingBuilder.bind(txQueue).to(ackExchange).with("confirm");
//    }

    /*--------------------消息可靠性消费--------------------*/
    @Bean
    public Queue ackQueue() {
        return QueueBuilder
                .durable("springAckQueue")
                .build();
    }


    @Bean
    public Queue limitQueue() {
        return QueueBuilder
                .durable("springLimitQueue")
                .build();
    }

    //--------------可持久化--------------
    @Bean
    public DirectExchange durableExchange() {
        return  ExchangeBuilder
                .directExchange("springDurableExchange")
                .durable(true)
                .build();
    }

    @Bean
    public Queue durableQueue() {
        //durable()/nonDurable/setDurable()、exclusive()、autoDelete()三个主要参数
        //withArgument(String key, Object value)用来设置单个额外属性，如withArgument("x-message-ttl", 25000)用来设置25秒自动删除
        //withArguments(Map<String, Object> arguments)用来一次性设置多个额外属性
        return QueueBuilder
                .durable("springDurableQueue")
                .build();
    }

    //配置绑定
    @Bean
    public Binding durableBinding(Queue durableQueue, DirectExchange durableExchange) {
        return BindingBuilder.bind(durableQueue).to(durableExchange).with("durableKey");
    }

    //Spring中Message是缺省持久化的
    @Bean
    public MessageConverter myMessageConverter() {
        SimpleMessageConverter myConverter=new SimpleMessageConverter();
//        Jackson2JsonMessageConverter jsonMessageConverter = new Jackson2JsonMessageConverter();
        return  myConverter;
    }

    /*--------------------死信--------------------*/
    @Bean
    public Exchange normalExchange() {
        return ExchangeBuilder.directExchange("springNormalExchange").durable(true).build();
    }

    @Bean
    public Queue normalQueue() {
        Map<String, Object> args = new HashMap<>(2);
        //声明死信Exchange
        args.put("x-dead-letter-exchange", "springDeadExchange");
        //声明死信队列重定向routingKey
        args.put("x-dead-letter-routing-key", "springDeadRoutingKey");
        //绑定死信属性
        return QueueBuilder.durable("springNormalQueue").withArguments(args).build();
    }

    @Bean
    public Binding normalBinding() {
        return new Binding("springNormalQueue", Binding.DestinationType.QUEUE, "springNormalExchange", "springNormalRoutingKey", null);
    }

    //定义死信交换器，与类型没有关系 不一定为directExchange
    @Bean
    public Exchange deadLetterExchange() {
        return ExchangeBuilder.directExchange("springDeadExchange").durable(true).build();
    }

    //声明死信队列
    @Bean
    public Queue deadLetterQueue() {
        return QueueBuilder.durable("springDeadQueue").build();
    }

    //死信队列绑定到死信交换器上
    @Bean
    public Binding deadLetterBinding() {
        return new Binding("springDeadQueue", Binding.DestinationType.QUEUE, "springDeadExchange", "springDeadRoutingKey", null);
    }

    @Bean
    public Queue redirectQueue() {
        return QueueBuilder.durable("springRedirectQueue").build();
    }

    @Bean
    public Binding redirectBinding() {
        return new Binding("springRedirectQueue", Binding.DestinationType.QUEUE, "springDeadExchange", "springRedirectRoutingKey", null);
    }
    /*--------------------延迟消息--------------------*/
    @Bean("delay")
    public DirectExchange delayExchange() {
        return ExchangeBuilder.directExchange("springDelayExchange").durable(true).delayed().build();
    }


    @Bean
    public Queue delayQueue() {
        return QueueBuilder.durable("springDelayQueue").build();
    }

    @Bean
    public Binding delayBinding() {
        return new Binding("springDelayQueue", Binding.DestinationType.QUEUE, "springDelayExchange", "springDelayRoutingKey", null);
//        return BindingBuilder.bind(delayQueue).to(delayExchange).with("springDelayRoutingKey");
    }
}
